/**
 * 预约功能测试文件
 *
 * 测试单进程和多进程预约功能
 *
 * 使用方法：
 * 1. 配置测试数据（修改 createTestAppointment 函数）
 * 2. 运行测试：node scripts/test-booking.mjs single
 *
 * 或者在开发环境中通过主进程调用
 */

// 注意：路径别名 @shared 需要在运行前通过 tsconfig-paths 注册
// 安装依赖: npm install -D tsconfig-paths
// 路径别名会在测试脚本或主进程中自动注册

import type { AppointmentManagement } from '@shared/types/'
import type { AppConfig } from '@shared/types/config'
import { loadConfig, updateConfig } from '../../../config/index'
import { setupLogger } from '../../../logger/index'
import { getUnifiedBookingService } from '../../booking-service'

/**
 * 创建测试用的预约数据
 */
function createTestAppointment(overrides?: Partial<AppointmentManagement>): AppointmentManagement {
  const now = new Date()
  return {
    id: Math.floor(Math.random() * 1000000),
    sequence_number: `TEST${Date.now()}`,
    passport_number: 'E12345678', // 请修改为实际测试用的护照号
    license_number: '440123199001011234', // 请修改为实际测试用的驾照号
    full_name: '测试用户',
    email: 'test@example.com',
    phone_number: '13800138000',
    issuing_country: 'CN',
    issuing_authority: 'GD',
    service_type: 'DI',
    preferred_dates: JSON.stringify(['25-12-2024', '26-12-2024']), // 请修改为实际的可用日期
    preferred_times: JSON.stringify(['09:00-10:00', '14:00-15:00']),
    priority: 2,
    remarks: '测试预约',
    is_placeholder: false,
    is_monitor: false,
    appointment_status: 'pending',
    office_code: 'HKLO',
    booking_mode: 'manual',
    retry_count: 0,
    created_at: now,
    updated_at: now,
    ...overrides,
  }
}

/**
 * 单个预约测试（单进程模式）
 */
export async function testSingleBooking(): Promise<void> {
  console.log('='.repeat(60))
  console.log('开始单进程预约测试')
  console.log('='.repeat(60))

  try {
    // 初始化配置和日志
    await loadConfig()
    await setupLogger()

    // 确保使用单进程模式
    await updateConfig({
      booking: {
        multiprocess: {
          enabled: false,
        },
      },
    } as Partial<AppConfig>)

    const service = getUnifiedBookingService()
    const appointment = createTestAppointment()

    console.log('测试数据：')
    console.log(`  护照号: ${appointment.passport_number}`)
    console.log(`  驾照号: ${appointment.license_number}`)
    console.log(`  姓名: ${appointment.full_name}`)
    console.log(`  办事处: ${appointment.office_code}`)
    console.log()

    console.log('开始执行预约（Request 模式）...')
    const startTime = Date.now()

    const result = await service.bookWith('request', appointment, {
      timeoutMs: 60000,
      preferredDates: ['25-12-2024', '26-12-2024'],
      preferredTimes: ['09:00-10:00', '14:00-15:00'],
      onProgress: (progress) => {
        console.log(`  进度: ${progress.progress}% - ${progress.step}`)
      },
    })

    const duration = Date.now() - startTime

    console.log()
    console.log('预约结果：')
    console.log(`  成功: ${result.success}`)
    if (result.success) {
      console.log(`  参考号: ${result.referenceNumber || 'N/A'}`)
      console.log(`  日期: ${result.selectedDate || 'N/A'}`)
      console.log(`  时段: ${result.selectedTimeslot || 'N/A'}`)
    }
    else {
      console.log(`  错误: ${result.error}`)
    }
    console.log(`  耗时: ${duration}ms`)
    console.log('='.repeat(60))

    // 清理
    await service.shutdown()
  }
  catch (error) {
    console.error('测试失败:', error)
    throw error
  }
}

/**
 * 多个预约测试（多进程模式）
 */
export async function testMultiProcessBooking(count: number = 5): Promise<void> {
  console.log('='.repeat(60))
  console.log(`开始多进程预约测试（${count} 个预约）`)
  console.log('='.repeat(60))

  try {
    // 初始化配置和日志
    await loadConfig()
    await setupLogger()

    // 启用多进程模式，使用少量 Worker 进行测试
    await updateConfig({
      booking: {
        multiprocess: {
          enabled: true,
          maxWorkers: Math.min(count, 10), // 测试时最多使用 10 个 Worker
          minWorkers: 3,
        },
      },
    } as Partial<AppConfig>)

    const service = getUnifiedBookingService()
    const appointments: AppointmentManagement[] = []

    // 创建多个测试预约
    for (let i = 0; i < count; i++) {
      appointments.push(createTestAppointment({
        id: Math.floor(Math.random() * 1000000) + i,
        sequence_number: `TEST${Date.now()}_${i}`,
        passport_number: `E1234567${i % 10}`, // 修改为不同的测试数据
        full_name: `测试用户${i + 1}`,
        email: `test${i + 1}@example.com`,
        priority: i % 3 + 1, // 不同的优先级
      }))
    }

    console.log(`创建了 ${appointments.length} 个测试预约`)
    console.log()

    // 并发执行所有预约
    const startTime = Date.now()
    const promises = appointments.map((appointment, index) => {
      return service.bookWith('request', appointment, {
        timeoutMs: 60000,
        priority: appointment.priority,
        preferredDates: ['25-12-2024', '26-12-2024'],
        preferredTimes: ['09:00-10:00', '14:00-15:00'],
        onProgress: (progress) => {
          console.log(`  [预约 ${index + 1}] ${progress.progress}% - ${progress.step}`)
        },
      }).then(result => ({
        index: index + 1,
        appointment,
        result,
      }))
    })

    const results = await Promise.allSettled(promises)
    const duration = Date.now() - startTime

    // 统计结果
    let successCount = 0
    let failedCount = 0

    console.log()
    console.log('预约结果汇总：')
    console.log('-'.repeat(60))

    results.forEach((settled, index) => {
      if (settled.status === 'fulfilled') {
        const { result } = settled.value
        if (result.success) {
          successCount++
          console.log(`✓ 预约 ${index + 1}: 成功 - 参考号: ${result.referenceNumber || 'N/A'}`)
        }
        else {
          failedCount++
          console.log(`✗ 预约 ${index + 1}: 失败 - ${result.error}`)
        }
      }
      else {
        failedCount++
        console.log(`✗ 预约 ${index + 1}: 异常 - ${settled.reason}`)
      }
    })

    console.log('-'.repeat(60))
    console.log(`总计: ${results.length} 个预约`)
    console.log(`成功: ${successCount} 个`)
    console.log(`失败: ${failedCount} 个`)
    console.log(`总耗时: ${duration}ms`)
    console.log(`平均耗时: ${Math.round(duration / results.length)}ms/个`)

    // 显示多进程统计信息
    const stats = service.getStats()
    if (stats) {
      console.log()
      console.log('多进程统计：')
      console.log(`  队列长度: ${stats.queueLength}`)
      console.log(`  待处理: ${stats.pendingCount}`)
      console.log(`  Worker总数: ${stats.workerStats.total}`)
      console.log(`  空闲Worker: ${stats.workerStats.idle}`)
      console.log(`  忙碌Worker: ${stats.workerStats.busy}`)
    }

    console.log('='.repeat(60))

    // 清理
    await service.shutdown()
  }
  catch (error) {
    console.error('测试失败:', error)
    throw error
  }
}

/**
 * 性能对比测试：单进程 vs 多进程
 */
export async function testPerformanceComparison(count: number = 5): Promise<void> {
  console.log('='.repeat(60))
  console.log('性能对比测试：单进程 vs 多进程')
  console.log('='.repeat(60))

  // 单进程测试
  console.log('\n1. 单进程模式测试')
  await loadConfig()
  await setupLogger()
  await updateConfig({
    booking: {
      multiprocess: {
        enabled: false,
      },
    },
  } as Partial<AppConfig>)

  const singleService = getUnifiedBookingService()
  const appointments = Array.from({ length: count }, (_, i) => createTestAppointment({
    id: i + 1,
    sequence_number: `SINGLE${Date.now()}_${i}`,
  }))

  const singleStart = Date.now()
  const singleResults = await Promise.allSettled(
    appointments.map(app => singleService.bookWith('request', app, { timeoutMs: 60000 })),
  )
  const singleDuration = Date.now() - singleStart
  const singleSuccess = singleResults.filter(r => r.status === 'fulfilled' && r.value.success).length

  await singleService.shutdown()

  // 多进程测试
  console.log('\n2. 多进程模式测试')
  await updateConfig({
    booking: {
      multiprocess: {
        enabled: true,
        maxWorkers: Math.min(count, 10),
      },
    },
  } as Partial<AppConfig>)

  const multiService = getUnifiedBookingService()
  const multiAppointments = Array.from({ length: count }, (_, i) => createTestAppointment({
    id: i + 1,
    sequence_number: `MULTI${Date.now()}_${i}`,
  }))

  const multiStart = Date.now()
  const multiResults = await Promise.allSettled(
    multiAppointments.map(app => multiService.bookWith('request', app, { timeoutMs: 60000 })),
  )
  const multiDuration = Date.now() - multiStart
  const multiSuccess = multiResults.filter(r => r.status === 'fulfilled' && r.value.success).length

  await multiService.shutdown()

  // 对比结果
  console.log('\n对比结果：')
  console.log('-'.repeat(60))
  console.log(`单进程模式:`)
  console.log(`  耗时: ${singleDuration}ms`)
  console.log(`  成功: ${singleSuccess}/${count}`)
  console.log(`  平均: ${Math.round(singleDuration / count)}ms/个`)
  console.log()
  console.log(`多进程模式:`)
  console.log(`  耗时: ${multiDuration}ms`)
  console.log(`  成功: ${multiSuccess}/${count}`)
  console.log(`  平均: ${Math.round(multiDuration / count)}ms/个`)
  console.log()
  console.log(`性能提升: ${Math.round((singleDuration - multiDuration) / singleDuration * 100)}%`)
  console.log('='.repeat(60))
}

/**
 * 主测试函数
 */
async function main() {
  const args = process.argv.slice(2)
  const testType = args[0] || 'single'

  try {
    switch (testType) {
      case 'single':
        await testSingleBooking()
        break
      case 'multi': {
        const count = Number.parseInt(args[1] || '5', 10)
        await testMultiProcessBooking(count)
        break
      }
      case 'compare': {
        const compareCount = Number.parseInt(args[1] || '5', 10)
        await testPerformanceComparison(compareCount)
        break
      }
      default:
        console.log('用法:')
        console.log('  node booking-test.ts single          # 单个预约测试')
        console.log('  node booking-test.ts multi [count]   # 多进程预约测试（默认5个）')
        console.log('  node booking-test.ts compare [count] # 性能对比测试（默认5个）')
    }
  }
  catch (error) {
    console.error('测试执行失败:', error)
    process.exit(1)
  }
}

// 如果直接运行此文件，执行测试
if (require.main === module) {
  main().catch(console.error)
}
